package cn.tanghom.app.oa.controller;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.FormService;
import org.flowable.engine.HistoryService;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.impl.RepositoryServiceImpl;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.image.impl.DefaultProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import cn.tanghom.app.oa.model.Leave;
import cn.tanghom.app.oa.model.LeaveTask;
import cn.tanghom.app.oa.model.RunningProcess;
import cn.tanghom.app.oa.service.LeaveService;
import cn.tanghom.app.system.model.Role;
import cn.tanghom.app.system.model.User;
import cn.tanghom.app.system.service.UserService;
import cn.tanghom.conf.CommonKey;
import cn.tanghom.support.page.Pager;
import cn.tanghom.support.utils.CommonUtils;
import cn.tanghom.support.web.ContextHolder;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import static cn.tanghom.support.web.BaseController.THEME_PATH;

/**
 * 请假流程，实现版本三，使用bootgrid显示结果
 * 此控制器的页面只需要返回html body
 * @author Hunteron-cp
 *
 */
@Controller("leaveController3")
public class ActivitiController implements CommonKey{
	@Autowired
	RepositoryService rep;
	@Autowired
	RuntimeService runservice;
	@Autowired
	FormService formservice;
	@Autowired
	IdentityService identityservice;
	@Autowired
	LeaveService leaveservice;
	@Autowired
	TaskService taskservice;
	@Autowired
	HistoryService histiryservice;	
	@Autowired
	UserService userService;
	
	
	
	@RequestMapping("/oa")
	String index(){
		return THEME_PATH+"/oa/index";
	}
	
	
	@RequestMapping("/processlist")
	String process(){
		return  THEME_PATH+"/oa/activiti/processlist";
	}
	
	
	@RequestMapping(value="/getprocesslists")
	@ResponseBody
	public Pager<JSONObject> getlist(@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
		int firstrow=(current-1)*rowCount;
		List<ProcessDefinition> list = rep.createProcessDefinitionQuery().listPage(firstrow, rowCount);
		int total = rep.createProcessDefinitionQuery().list().size();		
		
		Pager<JSONObject> grid = new Pager<JSONObject>();
		List<JSONObject> list2 = new ArrayList<>(list.size());
		for(ProcessDefinition pd:list){
			JSONObject obj = new JSONObject();
			obj.put("id",pd.getId());
			obj.put("name",pd.getName());
			obj.put("category",pd.getCategory());
			obj.put("key",pd.getKey());
			obj.put("description",pd.getDescription());
			obj.put("resourceName",pd.getResourceName());
			list2.add(obj);
		}
		grid.setCurrent(current);
		grid.setRowCount(rowCount);
		grid.setItems(list2);
		grid.setTotal(total);
		return grid;
	}
	
	
	
	@RequestMapping("/showresource")
	public void export(@RequestParam("pdid") String pdid,@RequestParam("resource") String resource,HttpServletResponse response) throws Exception{
		ProcessDefinition def=rep.createProcessDefinitionQuery().processDefinitionId(pdid).singleResult();
		InputStream is=rep.getResourceAsStream(def.getDeploymentId(), resource);
		ServletOutputStream output = response.getOutputStream();
		IOUtils.copy(is, output);
	}
	
	@RequestMapping("/deletedeploy")
	public String deletedeploy(@RequestParam("deployid") String deployid) throws Exception{
		rep.deleteDeployment(deployid,true);
		return THEME_PATH+"/oa/activiti/processlist";
	}
	
	@RequestMapping("/runningprocess")
	public String task(){
		return THEME_PATH+"/oa/activiti/runningprocess";
	} 
	
	
	 /**
     * 签收任务
     */
    @RequestMapping(value = "/task/claim/{id}")
    @ResponseBody
    public String claim(@PathVariable("id") String taskId) {
        try {
            User loger = ContextHolder.getUser();
            taskservice.claim(taskId, loger.getLoginName());
            return CommonUtils.msgCallback(true, "签收任务成功", "", null);
        } catch (Exception e) {
            return CommonUtils.msgCallback(false, "系统内部错误,请联系管理员，" + e.getMessage(), "", null);

        }
    }
    
	
	@RequestMapping("/deptleaderaudit")
	public String mytask(){
		return THEME_PATH+"/oa/activiti/deptleaderaudit"; 
	}
	
	@RequestMapping("/hraudit")
	public String hr(){
		return THEME_PATH+"/oa/activiti/hraudit"; 
	}	
	
	
	
	@RequestMapping("/leaveapply")
	public String leave(){
		return THEME_PATH+"/oa/activiti/leaveapply"; 
	}
	
	@RequestMapping("/reportback")
	public String reprotback(){
		return THEME_PATH+"/oa/activiti/reportback"; 
	}
	
	@RequestMapping("/modifyapply")
	public String modifyapply(){
		return THEME_PATH+"/oa/activiti/modifyapply"; 
	}
	@RequestMapping(value="/startleave",method=RequestMethod.POST)
	@ResponseBody
	public String start_leave(Leave apply,HttpSession session){
		String userid=(String) session.getAttribute("username");
		Map<String,Object> variables=new HashMap<String, Object>();
		variables.put("applyuserid", userid);
		ProcessInstance ins=leaveservice.startWorkflow(apply, variables);
		System.out.println("流程id"+ins.getId()+"已启动");
		return JSON.toJSONString("sucess");
	}
	
	@RequestMapping(value="/depttasklist",produces = {"application/json;charset=UTF-8"})
	@ResponseBody
	public Pager<LeaveTask> getdepttasklist(HttpSession session,@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
		Pager<LeaveTask> grid = new Pager<LeaveTask>();
		grid.setRowCount(rowCount);
		grid.setCurrent(current);
		grid.setTotal(0);
		grid.setItems(new ArrayList<LeaveTask>());
		//先做权限检查，对于没有部门领导审批权限的用户,直接返回空
		String userid=(String) session.getAttribute("username");		
		User user = userService.findByLoginName(userid);
		List<Role> userroles=user.getRoles();
		if(userroles==null)
			return grid;
		boolean flag=false;//默认没有权限
		for(int k=0;k<userroles.size();k++){
			Role r = userroles.get(k);			
			
			if(r.getRoleKey().equalsIgnoreCase("deptLeader"))
				flag=true;
			else
				continue;
		}
		if(flag==false)//无权限
		{
			return grid;
		}else{
			int firstrow=(current-1)*rowCount;
			List<Leave> results=leaveservice.getpagedepttask(userid,firstrow,rowCount);
			int totalsize=leaveservice.getalldepttask(userid);
			List<LeaveTask> tasks=new ArrayList<LeaveTask>();
			for(Leave apply:results){
				LeaveTask task=new LeaveTask(apply);
				
				tasks.add(task);
			}
			grid.setRowCount(rowCount);
			grid.setCurrent(current);
			grid.setTotal(totalsize);
			grid.setItems(tasks);
			return grid;
		}
	}
	
	@RequestMapping(value="/hrtasklist",produces = {"application/json;charset=UTF-8"})
	@ResponseBody
	public Pager<LeaveTask> gethrtasklist(HttpSession session,@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
		Pager<LeaveTask> grid=new Pager<LeaveTask>();
		grid.setRowCount(rowCount);
		grid.setCurrent(current);
		grid.setTotal(0);
		grid.setItems(new ArrayList<LeaveTask>());
		//先做权限检查，对于没有人事权限的用户,直接返回空
		String userid=(String) session.getAttribute("username");		
		User user = userService.findByLoginName(userid);
		List<Role> userroles=user.getRoles();
		if(userroles==null)
			return grid;
		boolean flag=false;//默认没有权限
		for(int k=0;k<userroles.size();k++){
			Role r = userroles.get(k);			
			
			if(r.getRoleKey().equalsIgnoreCase("hr"))
				flag=true;
			else
				continue;
		}
		if(flag==false)//无权限
		{
			return grid;
		}else{
			int firstrow=(current-1)*rowCount;
			List<Leave> results=leaveservice.getpagehrtask(userid,firstrow,rowCount);
			int totalsize=leaveservice.getallhrtask(userid);
			List<LeaveTask> tasks=new ArrayList<LeaveTask>();
			for(Leave apply:results){
				LeaveTask task=new LeaveTask(apply);
				tasks.add(task);
			}
			grid.setRowCount(rowCount);
			grid.setCurrent(current);
			grid.setTotal(totalsize);
			grid.setItems(tasks);
			return grid;
		}
	}
	
	@RequestMapping(value="/xjtasklist",produces = {"application/json;charset=UTF-8"})
	@ResponseBody
	public String getXJtasklist(HttpSession session,@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
		int firstrow=(current-1)*rowCount;
		String userid=(String) session.getAttribute("username");
		List<Leave> results=leaveservice.getpageXJtask(userid,firstrow,rowCount);
		int totalsize=leaveservice.getallXJtask(userid);
		List<LeaveTask> tasks=new ArrayList<LeaveTask>();
		for(Leave apply:results){
			LeaveTask task=new LeaveTask(apply);
			tasks.add(task);			
		}
		Pager<LeaveTask> grid=new Pager<LeaveTask>();
		grid.setRowCount(rowCount);
		grid.setCurrent(current);
		grid.setTotal(totalsize);
		grid.setItems(tasks);
		return JSON.toJSONString(grid);
	}
	
	
	@RequestMapping(value="/updatetasklist",produces = {"application/json;charset=UTF-8"})
	@ResponseBody
	public String getupdatetasklist(HttpSession session,@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
		int firstrow=(current-1)*rowCount;
		String userid=(String) session.getAttribute("username");
		List<Leave> results=leaveservice.getpageupdateapplytask(userid,firstrow,rowCount);
		int totalsize=leaveservice.getallupdateapplytask(userid);
		List<LeaveTask> tasks=new ArrayList<LeaveTask>();
		for(Leave apply:results){
			LeaveTask task=new LeaveTask(apply);
			tasks.add(task);
		}
		Pager<LeaveTask> grid=new Pager<LeaveTask>();
		grid.setRowCount(rowCount);
		grid.setCurrent(current);
		grid.setTotal(totalsize);
		grid.setItems(tasks);
		return JSON.toJSONString(grid);
	}
	
	@RequestMapping(value="/dealtask")
	@ResponseBody
	public String taskdeal(@RequestParam("taskid") String taskid,HttpServletResponse response){
		Task task=taskservice.createTaskQuery().taskId(taskid).singleResult();
		ProcessInstance process=runservice.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
		Leave leave=leaveservice.findById(Long.parseLong(process.getBusinessKey()));
		return JSON.toJSONString(leave);
	}
	
	@RequestMapping(value="/activiti/task-deptleaderaudit")
	String url(){
		return "/activiti/task-deptleaderaudit";
	}
	
	@RequestMapping(value="/task/deptcomplete/{taskid}")
	@ResponseBody
	public String deptcomplete(HttpSession session,@PathVariable("taskid") String taskid,HttpServletRequest req){
		String userid=(String) session.getAttribute("username");
		Map<String,Object> variables=new HashMap<String,Object>();
		String approve=req.getParameter("deptleaderapprove");
		variables.put("deptleaderapprove", approve);
		taskservice.claim(taskid, userid);
		taskservice.complete(taskid, variables);
		return JSON.toJSONString("success");
	}
	
	@RequestMapping(value="/task/hrcomplete/{taskid}")
	@ResponseBody
	public String hrcomplete(HttpSession session,@PathVariable("taskid") String taskid,HttpServletRequest req){
		String userid=(String) session.getAttribute("username");
		Map<String,Object> variables=new HashMap<String,Object>();
		String approve=req.getParameter("hrapprove");
		variables.put("hrapprove", approve);
		taskservice.claim(taskid, userid);
		taskservice.complete(taskid, variables);
		return JSON.toJSONString("success");
	}
	
	@RequestMapping(value="/task/reportcomplete/{taskid}")
	@ResponseBody
	public String reportbackcomplete(@PathVariable("taskid") String taskid,HttpServletRequest req){
		String realstart_time=req.getParameter("realstart_time");
		String realend_time=req.getParameter("realend_time");
		leaveservice.completereportback(taskid,realstart_time,realend_time);
		return JSON.toJSONString("success");
	}
	
	@RequestMapping(value="/task/updatecomplete/{taskid}")
	@ResponseBody
	public String updatecomplete(@PathVariable("taskid") String taskid,@ModelAttribute("leave") Leave leave,@RequestParam("reapply") String reapply){
		leaveservice.updatecomplete(taskid,leave,reapply);
		return JSON.toJSONString("success");
	}

	@RequestMapping("involvedprocess")//参与的正在运行的请假流程
	@ResponseBody
	public Pager<RunningProcess> allexeution(HttpSession session,@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
		int firstrow=(current-1)*rowCount;
		String userid=(String) session.getAttribute("username");
		ProcessInstanceQuery query = runservice.createProcessInstanceQuery();
		int total= (int) query.count();
		List<ProcessInstance> a = query.processDefinitionKey("leave").involvedUser(userid).listPage(firstrow, rowCount);
		List<RunningProcess> list=new ArrayList<RunningProcess>();
		for(ProcessInstance p:a){
			RunningProcess process=new RunningProcess();
			process.setActivityid(p.getActivityId());
			process.setBusinesskey(p.getBusinessKey());
			process.setExecutionid(p.getId());
			process.setProcessInstanceid(p.getProcessInstanceId());
			list.add(process);
		}
		Pager<RunningProcess> grid=new Pager<RunningProcess>();
		grid.setCurrent(current);
		grid.setRowCount(rowCount);
		grid.setTotal(total);
		grid.setItems(list);
		return grid;
	}
	
	@RequestMapping("/getfinishprocess")
	@ResponseBody
	public Pager<Leave> getHistory(HttpSession session,@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
		String userid=(String) session.getAttribute("username");
		HistoricProcessInstanceQuery process = histiryservice.createHistoricProcessInstanceQuery().processDefinitionKey("leave").startedBy(userid).finished();
		int total= (int) process.count();
		int firstrow=(current-1)*rowCount;
		List<HistoricProcessInstance> info = process.listPage(firstrow, rowCount);
		List<Leave> list=new ArrayList<Leave>();
		for(HistoricProcessInstance history:info){			
			String bussinesskey=history.getBusinessKey();
			Leave apply=leaveservice.findById(Long.parseLong(bussinesskey));
			apply.setHistoricProcessInstance(history);
			//apply.setProcessDefinition(history.getProcessDefinitionId());
			list.add(apply);
		}
		Pager<Leave> grid=new Pager<Leave>();
		grid.setCurrent(current);
		grid.setRowCount(rowCount);
		grid.setTotal(total);
		grid.setItems(list);
		return grid;
	}
	
	
	@RequestMapping("/historyprocess")
	public String history(){
		return THEME_PATH+"/oa/activiti/historyprocess";
	}
	
	
	@RequestMapping("/processinfo")
	@ResponseBody
	public List<HistoricActivityInstance> processinfo(@RequestParam("instanceid")String instanceid){
		List<HistoricActivityInstance> his = histiryservice.createHistoricActivityInstanceQuery().processInstanceId(instanceid).orderByHistoricActivityInstanceStartTime().asc().list();
		return his;
	}
	
	@RequestMapping("/processhis")
	@ResponseBody
	public List<HistoricActivityInstance> processhis(@RequestParam("ywh")String ywh){
		  String instanceid=histiryservice.createHistoricProcessInstanceQuery().processDefinitionKey("purchase").processInstanceBusinessKey(ywh).singleResult().getId();
		  System.out.println(instanceid);
		  List<HistoricActivityInstance> his = histiryservice.createHistoricActivityInstanceQuery().processInstanceId(instanceid).orderByHistoricActivityInstanceStartTime().asc().list();
		  return his;
	}
	
	@RequestMapping("myleaveprocess")
	String myleaveprocess(){
		return THEME_PATH+"/oa/activiti/myleaveprocess";
	}
	
	@RequestMapping("traceprocess/{executionid}")
	public void traceprocess(@PathVariable("executionid")String executionid,HttpServletResponse response) throws Exception{
		ProcessInstance process=runservice.createProcessInstanceQuery().processInstanceId(executionid).singleResult();
		BpmnModel bpmnmodel=rep.getBpmnModel(process.getProcessDefinitionId());
		List<String> activeActivityIds=runservice.getActiveActivityIds(executionid);
		DefaultProcessDiagramGenerator gen=new DefaultProcessDiagramGenerator();
		 // 获得历史活动记录实体（通过启动时间正序排序，不然有的线可以绘制不出来）  
	    List<HistoricActivityInstance> historicActivityInstances = histiryservice  
	            .createHistoricActivityInstanceQuery().executionId(executionid)  
	            .orderByHistoricActivityInstanceStartTime().asc().list();  
	    // 计算活动线  
	    List<String> highLightedFlows = leaveservice.getHighLightedFlows(  
	                    (ProcessDefinitionEntity) ((RepositoryServiceImpl) rep)  
	                            .getDeployedProcessDefinition(process.getProcessDefinitionId()),  
	                    historicActivityInstances); 
		
		InputStream in=gen.generateDiagram(bpmnmodel, "png", activeActivityIds,highLightedFlows,"宋体","宋体",null,null, 1.0);
	    //InputStream in=gen.generateDiagram(bpmnmodel, "png", activeActivityIds);
	    ServletOutputStream output = response.getOutputStream();
		IOUtils.copy(in, output);
	}
	
	@RequestMapping("myleaves")
	String myleaves(){
		return THEME_PATH+"/oa/activiti/myleaves";
	}
	
	@RequestMapping("setupprocess")
	@ResponseBody
	public Pager<RunningProcess> setupprocess(HttpSession session,@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
		int firstrow=(current-1)*rowCount;
		String userid=(String) session.getAttribute("username");
		ProcessInstanceQuery query = runservice.createProcessInstanceQuery();
		int total= (int) query.count();
		List<ProcessInstance> a = query.processDefinitionKey("leave").involvedUser(userid).listPage(firstrow, rowCount);
		List<RunningProcess> list=new ArrayList<RunningProcess>();
		for(ProcessInstance p:a){
			RunningProcess process=new RunningProcess();
			process.setActivityid(p.getActivityId());
			process.setBusinesskey(p.getBusinessKey());
			process.setExecutionid(p.getId());
			process.setProcessInstanceid(p.getProcessInstanceId());
			Leave l=leaveservice.findById(Long.parseLong(p.getBusinessKey()));
			if(l.getUserId().equals(userid))
				list.add(process);
			else
				continue;
		}
		Pager<RunningProcess> grid=new Pager<RunningProcess>();
		grid.setCurrent(current);
		grid.setRowCount(rowCount);
		grid.setTotal(total);
		grid.setItems(list);
		return grid;
	}
	
}
